
module ChessData
  
  # Class to store a set of chess games
  #
  # The usual way to create a database is directly from a filename. 
  # If your pgn file is called 'my_games.pgn', create a database using
  #
  #   Database.from_file 'my_games.pgn'
  #
  class Database
    include Enumerable

    def initialize
      @games = []
    end

    # Adds a given _game_ to the database.
    def << game
      @games << game
    end

    # Returns the game at the given _index_ value in the database.
    def [] index
      @games[index]
    end

    # Returns the number of games in the database.
    def size
      @games.size
    end

    # Returns a new database based on search criteria given in the block.
    # Each game is scanned to see if it meets the criteria. Also see Game#search.
    def search &block
      db = Database.new

      @games.each do |game|
        db << game if game.search(&block)
      end

      return db
    end

    # Add games from a specified filename to database.
    # filename:: the name of a pgn file from which to load games
    # encoding:: defaults to "iso-8859-1" (which works for TWIC files).
    def add_games_from filename, encoding: "iso-8859-1"
      File.open filename, mode: "r", encoding: encoding do |file|
        begin
          begin
            game = Game.from_pgn file
            @games << game unless game.nil?
          rescue ArgumentError
            puts "Error in #{filename}, previous game #{@games.last.white} vs #{@games.last.black}"
            return
          end
        end until file.eof?
      end
    end

    # Save the database in PGN format to given _filename_.
    # If filename exists, the games are _appended_ to the file.
    def to_file filename
      File.open(filename, "a") do |f|
        @games.each do |game|
          game.to_pgn f
          f.puts
        end
      end
    end

    # Loads and returns a new database based on given filename.
    # filename:: the name of a pgn file from which to load games
    # encoding:: defaults to "iso-8859-1" (which works for TWIC files).
    def Database.from_file filename, encoding: "iso-8859-1"
      database = Database.new
      database.add_games_from filename, encoding: encoding
      return database
    end
  end
end

